/*********************************************************************************
 *      Copyright:  (C) 2023 Lin XinCheng
 *                  All rights reserved.
 *
 *       Filename:  ds18b20app.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2023年07月22日)
 *         Author:  Lin XinCheng <1481155734@qq.com>
 *      ChangeLog:  1, Release initial version on "2023年07月22日 16时29分17秒"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <errno.h>

int ds18b20_get_temperature(float *temp);


int main (int argc, char **argv)
{
	float temp;/*  温度值有小数位，所以使用浮点数  */

	if( ds18b20_get_temperature(&temp) < 0)
	{
		printf("ERROR：get temperature from ds18b20 failure\n");
		return -1;
	}

	printf("ds18b20 temperature:%f 'C\n,"temp);

	return 0;
} 

int ds18b20_get_temperature(float *temp)
{
	const char	*w1_path = "/sys/class/w1_ds18b20/w1_ds18b20/";//设备路径
	char 		ds_path[50]; 	//文件采样路径
	char		buf[128];		//read()读数据存储的buffer
	DIR			*dirp;			//opendir()打开的文件夹句柄
	int 		fd = -1;		//open()打开文件的文件描述符
	char		*ptr;			//一个字符指针，用字符串处理
	int			rv = 0;			//函数返回值，默认成功返回0

	/*  在C语言编程时，进入函数的第一件事应该进行函数参数的合法性检测，检查参数非法输入。
	 *  * 否则调用者"不小心"通过 $temp 传入一个空指针，下面的代码就有可能出现段错误。
	 *  */
	if( !temp )
	{
		return -1;
	}

	 /* 我的驱动 打开 "/sys/class/w1_ds18b20/w1_ds18b20/" 文件夹，如果打开失败则打印错误信息并退出。 */
	if((dirp = opendir(w1_path)) == NULL)
	{
		printf("opendir error:%s\n",strerror(errno));
		return -2;
	}
	snprintf(ds_path, sizeof(ds_path), "%s/temp",w1_path); /* my_ds18b20_driver */

	/*  接下来打开 DS18B20 的采样文件，如果失败则返回相应的错误码-3。  */
	if( ( fd = open(ds_path, O_RDONLY)) < 0 )
	{
		printf("open ds_path error:%s\n",strerror(errno));
		return -3;
	}

	/*  读取文件中的内容将会触发 DS18B20温度传感器采样，这里读取文件内容保存到buf中  */
	if(read(fd, buf, sizeof(buf)) < 0 )
	{
		printf("read %s error:%s\n",ds_path, strerror(errno));

		/*  1, 这里不能直接调用 return -4 直接返回，否则的话前面open()打开的文件描述符就没有关闭。
		 *           * 这里设置 rv 为错误码-4，通过 goto 语句跳转到函数后面统一进行错误处理*/
		rv = -4;
		goto cleanup;
	}

	/*  采样温度值是在字符串"t="后面，这里我们从buf中找到"t="字符串的位置并保存到ptr指针 */
	ptr = strstr(buf, "t=");
	if(!ptr)
	{
		printf("error: can not get temperature\n");
		rv = -5;
		goto cleanup;
	}

	ptr += 2;
	*temp = atof(ptr)/1000;

cleanup:
	close(fd);
	return rv;

}

	

